﻿package com.sh.game.net
{
    import com.sh.game.consts.*;
    import com.sh.game.global.*;
    import com.sh.game.util.*;
    import flash.events.*;
    import flash.utils.*;
    import morn.core.handlers.*;
    import pluginfw.nio.*;
    import pluginfw.nio.filters.*;
    import pluginfw.nio.handler.*;
    import pluginfw.nio.message.*;

    public class Server extends Object
    {
        private var _host:String;
        private var _port:int;
        private var _messages:Array;
        private var _connectFunc:Function;
        private var _transports:Dictionary;
        private var _filters:Dictionary;
        private var _msgLog:Dictionary;
        private var _transType:Dictionary;
        private var _testHosts:Dictionary;
        private var _testHostsHandler:Dictionary;
        private var _testType:int = 0;
        private var closeHandler:Dictionary;
        protected var typeMessageids:Dictionary;
        private static var _instance:Server;

        public function Server()
        {
            this.closeHandler = new Dictionary();
            this.typeMessageids = new Dictionary();
            this._transports = new Dictionary();
            this._filters = new Dictionary();
            this._transType = new Dictionary();
            this._msgLog = new Dictionary();
            return;
        }// end function

        public function removeConnectByType(param1:int) : void
        {
            var _loc_2:Transport = null;
            if (this._transports[param1])
            {
                _loc_2 = this._transports[param1];
                _loc_2.disconnect();
                this.removeConnect(_loc_2);
                _loc_2.destroy();
            }
            return;
        }// end function

        public function getConnectByType(param1:int) : Transport
        {
            return this._transports[param1];
        }// end function

        public function testConnects(param1:Array, param2:int, param3:int, param4:Function = null) : void
        {
            var _loc_5:String = null;
            var _loc_6:Transport = null;
            var _loc_7:SimpleFilter = null;
            if (this._transports[param3])
            {
                return;
            }
            this._testHosts = new Dictionary();
            this._testHostsHandler = new Dictionary();
            this._testType = param3;
            for each (_loc_5 in param1)
            {
                
                _loc_6 = new Transport();
                _loc_7 = new SimpleFilter();
                _loc_6.setFilter(_loc_7);
                this._testHosts[_loc_6] = _loc_5;
                this._testHostsHandler[_loc_5] = param4;
                _loc_6.addEventListener(Event.CONNECT, this.testConnected);
                _loc_6.addEventListener(Event.CLOSE, this.connectFaild);
                _loc_6.addEventListener(IOErrorEvent.IO_ERROR, this.connectFaild);
                _loc_6.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.connectFaild);
                _loc_6.connect(_loc_5, param2);
            }
            return;
        }// end function

        protected function testConnected(event:Event) : void
        {
            var _loc_5:Object = null;
            var _loc_6:SimpleFilter = null;
            var _loc_2:* = event.currentTarget as Transport;
            var _loc_3:* = this._testHosts[event.currentTarget];
            var _loc_4:* = this._testHostsHandler[_loc_3];
            for (_loc_5 in this._testHosts)
            {
                
                if (_loc_5 != _loc_2)
                {
                    _loc_5.removeEventListener(Event.CLOSE, this.connectFaild);
                    _loc_5.removeEventListener(IOErrorEvent.IO_ERROR, this.connectFaild);
                    _loc_5.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.connectFaild);
                    _loc_5.removeEventListener(Event.CONNECT, this.testConnected);
                    _loc_5.disconnect();
                }
                this._testHosts[_loc_5] = null;
                delete this._testHosts[_loc_5];
                this._testHostsHandler[_loc_3] = null;
                delete this._testHostsHandler[_loc_3];
            }
            this._transType[_loc_2] = this._testType;
            this._transports[this._testType] = _loc_2;
            _loc_6 = new SimpleFilter();
            _loc_2.setFilter(_loc_6);
            this._filters[this._testType] = _loc_6;
            this._loc_4(_loc_3);
            _loc_2.addEventListener(Event.CLOSE, this.onClose);
            _loc_2.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
            _loc_2.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorHandler);
            return;
        }// end function

        protected function connectFaild(event:Event) : void
        {
            var _loc_2:* = this._testHosts[event.currentTarget];
            this._testHosts[event.currentTarget] = null;
            delete this._testHosts[event.currentTarget];
            this._testHostsHandler[_loc_2] = null;
            delete this._testHostsHandler[_loc_2];
            return;
        }// end function

        public function initRootConnect() : void
        {
            return;
        }// end function

        public function addConnect(param1:String, param2:int, param3:int, param4:Handler = null) : void
        {
            if (this._transports[param3])
            {
                return;
            }
            var _loc_5:* = new Transport();
            this._transType[_loc_5] = param3;
            this._transports[param3] = _loc_5;
            var _loc_6:* = new SimpleFilter();
            _loc_5.setFilter(_loc_6);
            this._filters[param3] = _loc_6;
            _loc_5.conenctSucHandler = param4;
            _loc_5.addEventListener(Event.CONNECT, this.connectSuccessHandler);
            _loc_5.addEventListener(Event.CLOSE, this.onClose);
            _loc_5.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
            _loc_5.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorHandler);
            _loc_5.connect(param1, param2);
            return;
        }// end function

        public function connectSuccessHandler(event:Event) : void
        {
            var _loc_2:* = event.currentTarget as Transport;
            if (_loc_2.conenctSucHandler)
            {
                _loc_2.conenctSucHandler.execute();
            }
            return;
        }// end function

        public function reconnect(param1:Transport) : void
        {
            param1.connectDelay(2000, param1.host, param1.port);
            return;
        }// end function

        public function securityErrorHandler(event:SecurityErrorEvent) : void
        {
            this.reconnect(event.currentTarget as Transport);
            return;
        }// end function

        public function addCloseHandler(param1:int, param2:Function) : void
        {
            this.closeHandler[param1] = param2;
            return;
        }// end function

        public function onClose(event:Event) : void
        {
            var _loc_3:Function = null;
            var _loc_2:* = this._transType[event.currentTarget];
            this.removeConnect(event.currentTarget);
            if (this.closeHandler[_loc_2])
            {
                _loc_3 = this.closeHandler[_loc_2];
                this._loc_3();
                this.closeHandler[_loc_2] = null;
                delete this.closeHandler[_loc_2];
            }
            return;
        }// end function

        public function ioErrorHandler(event:IOErrorEvent) : void
        {
            this.reconnect(event.currentTarget as Transport);
            return;
        }// end function

        private function removeConnect(param1:Object) : void
        {
            var _loc_2:int = 0;
            if (this._transType[param1] != null)
            {
                _loc_2 = this._transType[param1];
                this._filters[_loc_2] = null;
                delete this._filters[_loc_2];
                this._transports[_loc_2] = null;
                delete this._transports[_loc_2];
                this._transType[param1] = 0;
                delete this._transType[param1];
                param1.removeEventListener(Event.CLOSE, this.onClose);
                param1.removeEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
                param1.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorHandler);
                param1.destroy();
            }
            return;
        }// end function

        public function addHandler(param1:int, param2:int, param3:IGroupHandler) : void
        {
            if (this._filters[param1] != null)
            {
                this._filters[param1].addHandler(param2, param3);
                ;
            }
            return;
        }// end function

        public function getSendTime(param1:int) : int
        {
            return this._msgLog[param1];
        }// end function

        public function getMessageId(param1:int) : int
        {
            if (!this.typeMessageids[param1])
            {
                this.typeMessageids[param1] = 1;
            }
            var _loc_2:* = this.typeMessageids;
            var _loc_3:* = param1;
            _loc_2[_loc_3] = this.typeMessageids[param1] + 1;
            return this.typeMessageids[param1]++;
        }// end function

        public function send(param1:int, param2:int, param3, param4:int = 0, param5:int = 0, param6:Boolean = false) : Boolean
        {
            if (this._transports[param5])
            {
                if (Config.Log > LogType.DEBUG)
                {
                    Logger.log("发送消息：" + param1 + "----" + param2 + "----" + param3);
                }
                param4 = this.getMessageId(param5);
                if (param6)
                {
                    this._transports[param5].sendDirectMsg(param3);
                }
                else
                {
                    this._transports[param5].sendMessage(MessageFactory.createSimpleMessage(param1, param4, param2, param3));
                }
                return true;
            }
            return false;
        }// end function

        public function checkConnect(param1:int) : Boolean
        {
            if (this._transports[param1])
            {
                if (this._transports[param1].isConnect())
                {
                    return true;
                }
            }
            return false;
        }// end function

        public function sendBuffer(param1:int, param2:int, param3:ByteArray, param4:int = 0, param5:int = 0) : Boolean
        {
            if (this._transports[param5])
            {
                param4 = this.getMessageId(param5);
                if (Config.Log > LogType.DEBUG)
                {
                    Logger.log("发送消息：" + param1 + "----" + param2);
                }
                this._transports[param5].sendMessage(MessageFactory.createBufferMessage(param1, param4, param2, param3));
                return true;
            }
            return false;
        }// end function

        public static function get instance() : Server
        {
            if (_instance == null)
            {
                _instance = new Server;
            }
            return _instance;
        }// end function

    }
}
